package com.ruoyi.order.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.IpKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.model.RefundModel;
import com.ijpay.wxpay.model.UnifiedOrderModel;
import com.ruoyi.cinema.BO.GoodsBuyedMsgBo;
import com.ruoyi.cinema.DTO.*;
import com.ruoyi.order.VO.OrderVO;
import com.ruoyi.cinema.domain.*;
import com.ruoyi.cinema.event.GoodsBuyEvent;
import com.ruoyi.cinema.mapper.CinemaMapper;
import com.ruoyi.cinema.mapper.FilmMapper;
import com.ruoyi.cinema.mapper.FilmScheduleMapper;
import com.ruoyi.cinema.mapper.GoodsMapper;

import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.constant.WechatConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.constant.OrderConstant;
import com.ruoyi.order.DTO.ConfirmGoodsOrderYzDTO;
import com.ruoyi.order.DTO.ConfirmTicketOrderYzDTO;
import com.ruoyi.order.DTO.OrderInfoYzDTO;
import com.ruoyi.order.DTO.RefundOrderYzDTO;
import com.ruoyi.order.domain.*;
import com.ruoyi.order.mapper.*;
import com.ruoyi.order.service.IOrderService;
import com.ruoyi.utils.YzResult;
import com.ruoyi.utils.YzUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 订单Service业务层处理
 *
 * @author HHAOYU
 * @date 2020-12-14
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    private final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderPaymentMapper orderPaymentMapper;
    @Autowired
    private OrderRefundMapper orderRefundMapper;
    @Autowired
    private TicketOrderInfoMapper ticketOrderInfoMapper;
    @Autowired
    private TicketOrderTicketInfoMapper ticketOrderTicketInfoMapper;
    @Autowired
    private FilmMapper filmMapper;
    @Autowired
    private FilmScheduleMapper filmScheduleMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private MemberCardOrderMapper memberCardOrderMapper;
    @Autowired
    private CinemaMapper cinemaMapper;
    @Autowired
    private GoodsOrderInfoMapper goodsOrderInfoMapper;
    @Autowired
    private GoodsOrderGoodsInfoMapper goodsOrderGoodsInfoMapper;
    @Autowired
    private GoodsOrderComboInfoMapper goodsOrderComboInfoMapper;
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private OrderFulfillInfoMapper orderFulfillInfoMapper;
    @Autowired
    private ApplicationContext applicationContext;

    /**
     * 查询订单
     *
     * @param id 订单ID
     * @return 订单
     */
    @Override
    public Order selectOrderById(Long id)
    {
        return orderMapper.selectOrderById(id);
    }

    /**
     * 查询订单列表
     *
     * @param order 订单
     * @return 订单
     */
    @Override
    public List<Order> selectOrderList(Order order)
    {
        return orderMapper.selectOrderList(order);
    }

    /**
     * 新增订单
     *
     * @param order 订单
     * @return 结果
     */
    @Override
    public int insertOrder(Order order)
    {
        order.setCreateTime(DateUtils.getNowDate());
        return orderMapper.insertOrder(order);
    }

    /**
     * 修改订单
     *
     * @param order 订单
     * @return 结果
     */
    @Override
    public int updateOrder(Order order)
    {
        order.setUpdateTime(DateUtils.getNowDate());
        return orderMapper.updateOrder(order);
    }

    /**
     * 批量删除订单
     *
     * @param ids 需要删除的订单ID
     * @return 结果
     */
    @Override
    public int deleteOrderByIds(Long[] ids)
    {
        return orderMapper.deleteOrderByIds(ids);
    }

    /**
     * 删除订单信息
     *
     * @param id 订单ID
     * @return 结果
     */
    @Override
    public int deleteOrderById(Long id)
    {
        return orderMapper.deleteOrderById(id);
    }


    @Override
    public AjaxResult wechatPrePay(Long orderId, Long totalMoney, String openId, String outOrderNo, HttpServletRequest request, Long leftSecond, String body){
       return wechatPrePay(orderId,totalMoney,openId,outOrderNo,request,leftSecond,body, WechatConstants.WECHAT_NOTIFY_URL);
    }

    @Override
    public AjaxResult wechatPrePay(Long orderId, Long totalMoney, String openId, String outOrderNo, HttpServletRequest request, Long leftSecond, String body, String notifyUrl) {

        String ip = IpKit.getRealIp(request);
        if (StrUtil.isEmpty(ip)) {
            ip = "127.0.0.1";
        }
        Long a =  System.currentTimeMillis();
        String timeStartString = DateUtils.weChatTimeToString(a);
        Long expire = a + leftSecond*1000;
        String timeExpireString = DateUtils.weChatTimeToString(expire);
        Map<String, String> params = UnifiedOrderModel
                .builder()
                .appid(WechatConstants.APPID)
                .mch_id(WechatConstants.MCH_ID)
                .nonce_str(WxPayKit.generateStr())
                .body(body)
                .attach("中视电影购票")
                .out_trade_no(outOrderNo)
                .total_fee(String.valueOf(totalMoney))
                .spbill_create_ip(ip)
                .notify_url(notifyUrl)
                .trade_type(TradeType.JSAPI.getTradeType())
                .openid(openId)
                .time_start(timeStartString)
                .time_expire(timeExpireString)
                .build()
                .createSign(WechatConstants.WECHAT_KEY, SignType.HMACSHA256);

        // todo 这里要加上订单失效时间，防止用户在锁坐失效后，仍然还会付款

        logger.info(JSON.toJSONString(params));
        String xmlResult = WxPayApi.pushOrder(false, params);
        logger.info(xmlResult);


        Map<String, String> resultMap = WxPayKit.xmlToMap(xmlResult);
        String returnCode = resultMap.get("return_code");
        String returnMsg = resultMap.get("return_msg");
        if (!WxPayKit.codeIsOk(returnCode)) {
            return AjaxResult.error(-1,returnMsg);
        }
        String resultCode = resultMap.get("result_code");
        if (!WxPayKit.codeIsOk(resultCode)) {
            return AjaxResult.error(-1,returnMsg);
        }
        String prepayId = resultMap.get("prepay_id");

        Map<String, String> packageParams = WxPayKit.prepayIdCreateSign(prepayId, WechatConstants.APPID,
                WechatConstants.WECHAT_KEY, SignType.HMACSHA256);
        packageParams.put("orderId",String.valueOf(orderId));

        return AjaxResult.success(packageParams);
    }


    @Override
    public AjaxResult memberPay(Order order, Customer customer){

        ConfirmTicketOrderYzDTO confirmTicketOrderYzDTO = new ConfirmTicketOrderYzDTO();

        FilmSchedule fs = filmScheduleMapper.selectFilmScheduleByScheduleId(order.getScheduleId());
        String accessToken = customer.getAccessToken();
        confirmTicketOrderYzDTO.setMobile(customer.getPhone());
        confirmTicketOrderYzDTO.setCinemaLinkId(fs.getCinemaLinkId());
        confirmTicketOrderYzDTO.setScheduleId(fs.getScheduleId());
        confirmTicketOrderYzDTO.setScheduleKey(fs.getScheduleKey());
        confirmTicketOrderYzDTO.setLockOrderId(order.getLockOrderId());
        confirmTicketOrderYzDTO.setOutId(order.getOutId());
        confirmTicketOrderYzDTO.setOrderAmount(order.getOrderAmount());
        confirmTicketOrderYzDTO.setPayAmount(order.getPayAmount());
        confirmTicketOrderYzDTO.setPromoAmount(order.getPromoAmount());

        confirmTicketOrderYzDTO.setTicketList(order.getOrderTicketList());
        confirmTicketOrderYzDTO.setPaymentList(order.getOrderPaymentList());
        confirmTicketOrderYzDTO.setPromotionList(order.getOrderPromotionList());

        YzResult<ConfirmTicketRetYzDTO> ret = YzUtils.confirmTicketOrder(confirmTicketOrderYzDTO,accessToken);
        if(ret.getResultCode().equals(Constants.YZSUCCESS) && ret.getData().getBizCode().equals(Constants.BIZSUCCESS)){
            order.setYzOrderId(ret.getData().getBizData().getOrderId());
            order.setStatus(OrderConstant.ORDER_STATUS_CONFIRM_SUCCESS);
            order.setUpdateTime(new Date(System.currentTimeMillis()));
            orderMapper.updateOrder(order);
            getOrderInfo(order,fs.getCinemaLinkId(),order.getYzOrderId(),accessToken, customer);
            redisCache.deleteObject(order.getLockOrderId()+ Constants.LOCK_SEAT_KEY);
        }else {
            order.setStatus(OrderConstant.ORDER_STATUS_REFUND_SUCCESS);
            orderMapper.updateOrder(order);
            getFailedOrderInfo(order);
            redisCache.deleteObject(order.getLockOrderId()+ Constants.LOCK_SEAT_KEY);
            YzUtils.unlockSeat(fs.getCinemaLinkId(),order.getLockOrderId(),accessToken);
        }
        return AjaxResult.success(order);
    }


    @Override
    public AjaxResult goodsMemberPay(Order order, Customer customer){
        ConfirmGoodsOrderYzDTO confirmGoodsOrderYzDTO = new ConfirmGoodsOrderYzDTO();
        String accessToken = customer.getAccessToken();
        Cinema cinema = cinemaMapper.selectCinemaById(order.getCinemaId());
        confirmGoodsOrderYzDTO.setCinemaLinkId(cinema.getCinemaLinkId());
        confirmGoodsOrderYzDTO.setMobile(order.getMobile());
        confirmGoodsOrderYzDTO.setOutId(order.getOutId());
        confirmGoodsOrderYzDTO.setOrderAmount(order.getOrderAmount());
        confirmGoodsOrderYzDTO.setPayAmount(order.getPayAmount());
        confirmGoodsOrderYzDTO.setPromoAmount(order.getPromoAmount());
        confirmGoodsOrderYzDTO.setGoodsList(order.getOrderGoodsList());
        confirmGoodsOrderYzDTO.setPromotionList(order.getOrderPromotionList());
        confirmGoodsOrderYzDTO.setPaymentList(order.getOrderPaymentList());
        confirmGoodsOrderYzDTO.setFulfillInfo(order.getOrderFulfillInfo());

        YzResult<ConfirmTicketRetYzDTO> ret = YzUtils.confirmGoodsOrder(confirmGoodsOrderYzDTO,accessToken);
        if(ret.getResultCode().equals(Constants.YZSUCCESS) && ret.getData().getBizCode().equals(Constants.BIZSUCCESS)){
            order.setYzOrderId(ret.getData().getBizData().getOrderId());
            order.setStatus(OrderConstant.ORDER_STATUS_CONFIRM_SUCCESS);
            order.setUpdateTime(new Date(System.currentTimeMillis()));
            orderMapper.updateOrder(order);
            getOrderInfo(order,cinema.getCinemaLinkId(),order.getYzOrderId(),accessToken,customer);
        }else {
            order.setStatus(OrderConstant.ORDER_STATUS_REFUND_SUCCESS);
            orderMapper.updateOrder(order);
            getFailedOrderInfo(order);
        }
        return AjaxResult.success(order);
    }


    @Override
    public AjaxResult refundOrder(Order order, String accessToken, String cinemaLinkId, String outRefundNo){

        List<OrderPayment> paymentList = order.getOrderPaymentList();
        Long wechatFee = 0L;
        Long totalFee = 0L;
        String outTradeNo = "";
        for (OrderPayment op:paymentList) {
            if(op.getPayMethodCode().equals(OrderConstant.WEIXIN)){
                wechatFee += op.getPayAmount();
                outTradeNo = op.getPayCode();
                op.setRefundCode(outRefundNo);
                op.setRefundTime(new Date(System.currentTimeMillis()));
                orderPaymentMapper.updateOrderPayment(op);
            }
            totalFee +=op.getPayAmount();

        }

        OrderRefund orderRefund = new OrderRefund();
        orderRefund.setOrderId(order.getId());
        orderRefund.setWechatRefundAmount(wechatFee);
        orderRefund.setTotalAmount(totalFee);
        orderRefund.setRefundCode(outRefundNo);
        orderRefund.setOutTradeNo(outTradeNo);
        orderRefund.setStatus("0");
        orderRefund.setType(order.getType());
        orderRefundMapper.insertOrderRefund(orderRefund);
            //如果订单确认成功 则 先退票，再退款
        if(order.getStatus().equals(OrderConstant.ORDER_STATUS_CONFIRM_SUCCESS)){
            YzResult<RefundOrderYzDTO> refundOrderYzDTOYzResult = YzUtils.refundOrder(cinemaLinkId,order.getYzOrderId(),order.getOutId(),accessToken);
            if(refundOrderYzDTOYzResult.getResultCode().equals(Constants.YZSUCCESS) && refundOrderYzDTOYzResult.getData().getBizCode().equals(Constants.BIZSUCCESS)){
                String refundId = refundOrderYzDTOYzResult.getData().getBizData().getRefundId();
                if(null != refundId){
                    orderRefund.setYzRefundId(refundId);
                    if(wechatFee.equals(0L) || wechatRefund(orderRefund)){
                        order.setStatus(OrderConstant.ORDER_STATUS_REFUND_SUCCESS);
                        orderMapper.updateOrder(order);
                        orderRefund.setStatus("2");
                        orderRefundMapper.updateOrderRefund(orderRefund);
                        return AjaxResult.success("退款成功");
                    }
                    order.setStatus(OrderConstant.ORDER_STATUS_REFUND_TICKET_BUT_MONEY);
                    orderMapper.updateOrder(order);

                    orderRefund.setStatus("1");
                    orderRefundMapper.updateOrderRefund(orderRefund);
                }
            }
        }
        //如果订单确认失败，则直接退款
        if(order.getStatus().equals(OrderConstant.ORDER_STATUS_CONFIRM_FAIL)){
            if(wechatFee.equals(0L) || wechatRefund(orderRefund)){
                order.setStatus(OrderConstant.ORDER_STATUS_REFUND_SUCCESS);
                orderMapper.updateOrder(order);
                orderRefund.setStatus("2");
                orderRefundMapper.updateOrderRefund(orderRefund);
                return AjaxResult.success("退款成功");
            }
        }

        return AjaxResult.error(-1,"退款失败");
    }

    @Override
    public AjaxResult refundMemberOrder(MemberCardOrder memberCardOrder, String accessToken, String cinemaLinkId, String outRefundNo){

        OrderRefund orderRefund = new OrderRefund();
        orderRefund.setOrderId(memberCardOrder.getId());
        orderRefund.setWechatRefundAmount(memberCardOrder.getPayAmount());
        orderRefund.setTotalAmount(memberCardOrder.getPayAmount());
        orderRefund.setRefundCode(outRefundNo);
        orderRefund.setOutTradeNo(memberCardOrder.getPayCode());
        orderRefund.setStatus("0");
        orderRefund.setType(memberCardOrder.getType());
        if(wechatRefund(orderRefund)){
            memberCardOrder.setStatus(OrderConstant.MEMBER_RODER_STATUS_REFUND_SUCCESS);
            memberCardOrderMapper.updateMemberCardOrder(memberCardOrder);
            return AjaxResult.success("退款成功");
        }
        return AjaxResult.error(-1,"退款失败");
    }

    @Override
    public boolean wechatRefund(OrderRefund orderRefund) {
        try {

            Map<String, String> params = RefundModel.builder()
                    .appid(WechatConstants.APPID)
                    .mch_id(WechatConstants.MCH_ID)
                    .nonce_str(WxPayKit.generateStr())
                    .out_trade_no(orderRefund.getOutTradeNo())
                    .out_refund_no(orderRefund.getRefundCode()) //
                    .total_fee(String.valueOf(orderRefund.getWechatRefundAmount()))
                    .refund_fee(String.valueOf(orderRefund.getWechatRefundAmount()))//
                    .notify_url(WechatConstants.WECHAT_REFUND_NOTIFY_URL)
                    .build()
                    .createSign(WechatConstants.WECHAT_KEY, SignType.MD5);
            ClassPathResource cl = new ClassPathResource("apiclient_cert.p12");
            InputStream inputStream = cl.getInputStream();
            logger.info("refundParam: {}",params);
            String refundStr = WxPayApi.orderRefund(false, params, inputStream, WechatConstants.MCH_ID);
            logger.info("refundStr: {}", refundStr);


            Map<String, String> resultMap = WxPayKit.xmlToMap(refundStr);
            String returnCode = resultMap.get("return_code");
            String returnMsg = resultMap.get("return_msg");

            if (!WxPayKit.codeIsOk(returnCode)) {
                return false;
            }
            String resultCode = resultMap.get("result_code");
            if (!WxPayKit.codeIsOk(resultCode)) {
                return false;
            }
            return true;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
    @Override
    public boolean getOrderInfo(Order order ,String cinemaLinkId, String orderId, String accessToken, Customer customer){
        YzResult<OrderInfoYzDTO> orderInfoYzDTOResult = YzUtils.getOrderInfo(cinemaLinkId, orderId, accessToken);
        if(orderInfoYzDTOResult.getResultCode().equals(Constants.YZSUCCESS) && orderInfoYzDTOResult.getData().getBizCode().equals(Constants.BIZSUCCESS)){
            OrderInfoYzDTO orderInfoYzDTO = orderInfoYzDTOResult.getData().getBizData();
            if(null != orderInfoYzDTO){
                order.setOutId(orderInfoYzDTO.getOutId());
                orderMapper.updateOrder(order);

                if(null != orderInfoYzDTO.getTicketOrder()){
                    TicketOrderInfo ticketOrderInfo = orderInfoYzDTO.getTicketOrder();
                    ticketOrderInfo.setOrderId(order.getId());
                    //ticketOrderInfo.setPayAmount(order.getTicketPayAmount());
                    Film film = filmMapper.selectFilmByFilmCode(ticketOrderInfo.getFilmCode());
                    ticketOrderInfo.setPoster(film.getPoster());

                    ticketOrderInfoMapper.insertTicketOrderInfo(ticketOrderInfo);

                    List<TicketOrderTicketInfo> ticketList= ticketOrderInfo.getTicketList();
                    for (TicketOrderTicketInfo toti :ticketList) {
                        toti.setRowNa(toti.getRowName());
                        toti.setColumnNa(toti.getColumnName());
                        toti.setTicketOrderInfoId(ticketOrderInfo.getId());
                        ticketOrderTicketInfoMapper.insertTicketOrderTicketInfo(toti);
                    }
                }//todo goods还没有测试哦，
                if(null != orderInfoYzDTO.getGoodsOrder()){
                    GoodsOrderInfo goodsOrderInfo = orderInfoYzDTO.getGoodsOrder();
                    goodsOrderInfo.setOrderId(order.getId());
                    goodsOrderInfoMapper.insertGoodsOrderInfo(goodsOrderInfo);

                    List<GoodsOrderGoodsInfo> goodsList = goodsOrderInfo.getGoodsList();
                    for (GoodsOrderGoodsInfo gogi :goodsList) {
                        Goods go = new Goods();
                        go.setCinemaId(order.getCinemaId());
                        go.setGoodsCode(gogi.getGoodsCode());
                        List<Goods> gl = goodsMapper.selectGoodsList(go);
                        gogi.setGoodsPicUrl(gl.get(0).getGoodsPicUrl());
                        gogi.setGoodsOrderInfoId(goodsOrderInfo.getId());
                        goodsOrderGoodsInfoMapper.insertGoodsOrderGoodsInfo(gogi);
                        if(null != gogi.getComboList()){
                            for (GoodsOrderComboInfo goci :gogi.getComboList()) {
                                goci.setGoodsOrderGoodsInfoId(gogi.getId());
                                goodsOrderComboInfoMapper.insertGoodsOrderComboInfo(goci);
                            }
                        }
                    }
                    if(null != orderInfoYzDTO.getFulfillInfo()){
                        OrderFulfillInfo orderFulfillInfo = order.getOrderFulfillInfo();
                        orderFulfillInfo.setFulfillCode(orderInfoYzDTO.getFulfillInfo().getFulfillCode());
                        orderFulfillInfo.setFulfillStatus(orderInfoYzDTO.getFulfillInfo().getFulfillStatus());
                        orderFulfillInfo.setAppointFlag(orderInfoYzDTO.getFulfillInfo().getAppointFlag());
                        orderFulfillInfoMapper.updateOrderFulfillInfo(orderFulfillInfo);
                    }
                    GoodsBuyedMsgBo goodsBuyedMsgBo = new GoodsBuyedMsgBo(order,customer,cinemaLinkId);
                    GoodsBuyEvent goodsBuyEvent = new GoodsBuyEvent(goodsBuyedMsgBo);
                    applicationContext.publishEvent(goodsBuyEvent);
                }

            }
            return true;
        }else {
            return false;
        }
    }
    @Override
    public boolean getFailedOrderInfo(Order order){
        // todo 兼容goods 订单
        if(order.getType().equals(OrderConstant.ORDER_TYPE_TICKET)){
            FilmSchedule filmSchedule = filmScheduleMapper.selectFilmScheduleByScheduleId(order.getScheduleId());
            Film film = filmMapper.selectFilmById(filmSchedule.getFilmId());
            TicketOrderInfo ticketOrderInfo = new TicketOrderInfo();
            ticketOrderInfo.setOrderId(order.getId());
            ticketOrderInfo.setPayAmount(order.getTicketPayAmount());
            ticketOrderInfo.setPoster(film.getPoster());
            ticketOrderInfo.setFilmCode(filmSchedule.getFilmCode());
            ticketOrderInfo.setFilmName(film.getFilmName());
            ticketOrderInfo.setFilmShortName(film.getFilmName());
            ticketOrderInfo.setFilmLanguage(filmSchedule.getLanguage());
            ticketOrderInfo.setShowTime(filmSchedule.getShowDateTime());
            ticketOrderInfo.setHallCode(filmSchedule.getHallCode());
            ticketOrderInfo.setHallName(filmSchedule.getHallName());
            ticketOrderInfo.setScheduleId(filmSchedule.getScheduleId());
            ticketOrderInfo.setOrderAmount(order.getTicketPayAmount());
            ticketOrderInfoMapper.insertTicketOrderInfo(ticketOrderInfo);

            if(null != order.getOrderTicketList()){
                List<OrderTicket> orderTicketList = order.getOrderTicketList();
                for (OrderTicket ot :orderTicketList) {
                    String s= redisCache.getCacheMapValue(filmSchedule.getCinemaLinkId()+ Constants.CINEMA_HALL,filmSchedule.getHallCode());
                    SeatPlanYZALLDTO seatPlanYZALLDTO = JSON.parseObject(s, SeatPlanYZALLDTO.class);
                    SeatPlanYzDTO seatPlanYzDTO = seatPlanYZALLDTO.getSeatPlanList().get(0);
                    ti: for (SectionYZDTO syd :seatPlanYzDTO.getSectionList()) {
                        for(Seat seat :syd.getSeatList()){
                            if(ot.getSeatCode().equals(seat.getSeatCode())){
                                TicketOrderTicketInfo ticketOrderTicketInfo = new TicketOrderTicketInfo();
                                ticketOrderTicketInfo.setTicketOrderInfoId(ticketOrderInfo.getId());
                                ticketOrderTicketInfo.setColumnId(seat.getColumnId());
                                ticketOrderTicketInfo.setColumnNa(seat.getColumnName());
                                ticketOrderTicketInfo.setRowId(seat.getRowId());
                                ticketOrderTicketInfo.setRowNa(seat.getRowName());
                                ticketOrderTicketInfo.setSeatCode(seat.getSeatCode());
                                continue ti;
                            }
                        }
                    }
                }
            }
        }
        if(order.getType().equals(OrderConstant.ORDER_TYPE_GOODS)){
            GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
            goodsOrderInfo.setOrderId(order.getId());
            goodsOrderInfo.setOrderAmount(order.getOrderAmount());
            goodsOrderInfo.setPayAmount(order.getPayAmount());
            goodsOrderInfoMapper.insertGoodsOrderInfo(goodsOrderInfo);
            if(null != order.getOrderGoodsList()){
                for (OrderGoods orderGoods :order.getOrderGoodsList()) {
                    Goods goods = new Goods();
                    goods.setCinemaId(order.getCinemaId());
                    goods.setGoodsCode(orderGoods.getGoodsCode());
                    List<Goods> goodsList = goodsMapper.selectGoodsList(goods);
                    GoodsOrderGoodsInfo goodsOrderGoodsInfo = new GoodsOrderGoodsInfo();
                    goodsOrderGoodsInfo.setGoodsOrderInfoId(goodsOrderInfo.getId());
                    goodsOrderGoodsInfo.setGoodsCode(orderGoods.getGoodsCode());
                    goodsOrderGoodsInfo.setGoodsCount(orderGoods.getGoodsCount());
                    goodsOrderGoodsInfo.setGoodsName(goodsList.get(0).getGoodsName());
                    goodsOrderGoodsInfo.setGoodsPicUrl(goodsList.get(0).getGoodsPicUrl());
                    goodsOrderGoodsInfo.setGoodsPrice(goodsList.get(0).getGoodsSettlePrice());
                    goodsOrderGoodsInfoMapper.insertGoodsOrderGoodsInfo(goodsOrderGoodsInfo);
                    if(null != orderGoods.getComboList()){
                        for (OrderGoodsCombo orderGoodsCombo :orderGoods.getComboList()) {
                            GoodsOrderComboInfo goodsOrderComboInfo = new GoodsOrderComboInfo();
                            goodsOrderComboInfo.setGoodsOrderGoodsInfoId(goodsOrderGoodsInfo.getId());
                            goodsOrderComboInfo.setGoodsCode(orderGoodsCombo.getGoodsCode());
                            goodsOrderComboInfo.setGoodsName(orderGoodsCombo.getGoodsName());
                            goodsOrderComboInfo.setGoodsCount(orderGoodsCombo.getGoodsCount());
                            goodsOrderComboInfo.setGroupId(orderGoodsCombo.getGroupId());
                            //todo 没有groupName
                            goodsOrderComboInfoMapper.insertGoodsOrderComboInfo(goodsOrderComboInfo);
                        }
                    }
                }
            }
        }

        return true;
    }

    @Override
    public TableDataInfo selectGoodsOrderForApi(Order order){
        List<Order> orderList = orderMapper.selectOrderListPre(order);
        if(null == orderList || orderList.isEmpty()){
            return getDataTable(Collections.emptyList());
        }
        Long [] ids = orderList.stream().map(Order::getId).toArray(Long[]::new);
        TableDataInfo info = getDataTable(orderList);
        List<OrderVO> realOrderList = orderMapper.selectOrderForApiV2(ids);
        //更新订单
        for (OrderVO orderVO:realOrderList) {
            if(orderVO.getStatus().equals(OrderConstant.ORDER_STATUS_CONFIRM_SUCCESS) ||
                    (null != orderVO.getOrderFulfillInfo()
                            && null != orderVO.getOrderFulfillInfo().getFulfillStatus()
                            && !orderVO.getOrderFulfillInfo().getFulfillStatus().equals("FINISH")
                            && !orderVO.getOrderFulfillInfo().getFulfillStatus().equals("CANCEL"))){
                YzResult<OrderInfoYzDTO> yzDTOYzResult = YzUtils.getOrderInfoWithoutToken(orderVO.getCinemaLinkId(),orderVO.getYzOrderId());
                if(yzDTOYzResult.getResultCode().equals(Constants.YZSUCCESS) && yzDTOYzResult.getData().getBizCode().equals(Constants.BIZSUCCESS)){
                    OrderInfoYzDTO orderInfoYzDTO = yzDTOYzResult.getData().getBizData();
                    if(null != orderInfoYzDTO){
                        if(yzDTOYzResult.getResultCode().equals(Constants.YZSUCCESS)) {
                            if (orderVO.getStatus().equals(OrderConstant.ORDER_STATUS_CONFIRM_SUCCESS)
                                    && orderInfoYzDTO.getRefundFlag().equals("N")) {
                                Order od = new Order();
                                od.setId(orderVO.getId());
                                od.setStatus(OrderConstant.ORDER_STATUS_FINISHED);
                                od.setUpdateTime(DateUtils.getNowDate());
                                updateOrder(od);
                                orderVO.setStatus(OrderConstant.ORDER_STATUS_FINISHED);

                                if (null != orderInfoYzDTO.getGoodsOrder() && null != orderInfoYzDTO.getGoodsOrder().getGoodsList()) {
                                    List<GoodsOrderGoodsInfo> goodsOrderGoodsInfoList = orderInfoYzDTO.getGoodsOrder().getGoodsList();
                                    for (GoodsOrderGoodsInfo gogi : goodsOrderGoodsInfoList) {
                                        if (gogi.getPickupFlag().equals("Y")) {
                                            if (null != orderVO.getGoodsOrderInfo() && null != orderVO.getGoodsOrderInfo().getGoodsList()) {
                                                List<GoodsOrderGoodsInfo> toList = orderVO.getGoodsOrderInfo().getGoodsList();
                                                for (GoodsOrderGoodsInfo to : toList) {
                                                    if (to.getGoodsCode().equals(gogi.getGoodsCode())) {
                                                        to.setPickupFlag("Y");
                                                        goodsOrderGoodsInfoMapper.updateGoodsOrderGoodsInfo(to);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            if(null != orderInfoYzDTO.getFulfillInfo()){
                                OrderFulfillInfo orderFulfillInfo = orderVO.getOrderFulfillInfo();
                                if(null != orderFulfillInfo){
                                    if(null == orderFulfillInfo.getFulfillStatus() || !orderFulfillInfo.getFulfillStatus().equals(orderInfoYzDTO.getFulfillInfo().getFulfillStatus())){
                                        orderFulfillInfo.setFulfillStatus(orderInfoYzDTO.getFulfillInfo().getFulfillStatus());
                                        orderFulfillInfoMapper.updateOrderFulfillInfo(orderFulfillInfo);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        info.setRows(realOrderList);
        return info;
    }
    @Override
    public TableDataInfo selectTicketOrderForApi(Order order){
        List<Order> orderList = orderMapper.selectOrderListPre(order);
        if(null == orderList || orderList.isEmpty()){
            return getDataTable(Collections.emptyList());
        }
        Long [] ids = orderList.stream().map(Order::getId).toArray(Long[]::new);
        TableDataInfo info = getDataTable(orderList);
        List<OrderVO> realOrderList = orderMapper.selectOrderForApiV2(ids);
        // 更新订单
        for (OrderVO orderVO:realOrderList) {
            if(orderVO.getStatus().equals(OrderConstant.ORDER_STATUS_CONFIRM_SUCCESS)){
                YzResult<OrderInfoYzDTO> yzDTOYzResult = YzUtils.getOrderInfoWithoutToken(orderVO.getCinemaLinkId(),orderVO.getYzOrderId());
                if(yzDTOYzResult.getResultCode().equals(Constants.YZSUCCESS) && yzDTOYzResult.getData().getBizCode().equals(Constants.BIZSUCCESS)){
                    OrderInfoYzDTO orderInfoYzDTO = yzDTOYzResult.getData().getBizData();
                    if(null != orderInfoYzDTO){
                        if(orderInfoYzDTO.getRefundFlag().equals("N")){
                            Order od = new Order();
                            od.setId(orderVO.getId());
                            od.setStatus(OrderConstant.ORDER_STATUS_FINISHED);
                            od.setUpdateTime(DateUtils.getNowDate());
                            updateOrder(od);
                            orderVO.setStatus(OrderConstant.ORDER_STATUS_FINISHED);

                            if(null != orderInfoYzDTO.getTicketOrder() && null != orderInfoYzDTO.getTicketOrder().getTicketList()){
                                List<TicketOrderTicketInfo> ticketOrderTicketInfoList =  orderInfoYzDTO.getTicketOrder().getTicketList();
                                for (TicketOrderTicketInfo toti :ticketOrderTicketInfoList) {
                                    if(toti.getPrintFlag().equals("Y")){
                                        if(null != orderVO.getTicketOrderInfo() && null != orderVO.getTicketOrderInfo().getTicketList()){
                                            List<TicketOrderTicketInfo> toList =  orderVO.getTicketOrderInfo().getTicketList();
                                            for (TicketOrderTicketInfo to :toList) {
                                                if(to.getTicketNo().equals(toti.getTicketNo())){
                                                    to.setPrintFlag("Y");
                                                    ticketOrderTicketInfoMapper.updateTicketOrderTicketInfo(to);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        info.setRows(realOrderList);
        return info;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    private TableDataInfo getDataTable(List<?> list)
    {
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(list);
        PageInfo pageInfo = new PageInfo(list);
        rspData.setTotal(pageInfo.getTotal());
        rspData.setHasNextPage(pageInfo.isHasNextPage());
        return rspData;
    }


}
